import pandas as pd
import time
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import re
from operator import itemgetter
import xlwt
from matplotlib.font_manager import *  # 如果想在图上显示中文，需导入这个包
import shutil
from utils import write2txt


PEOPLE = {
    'xxx' :'the talker in chat.csv',
}


# 微信聊天数据统计
class WeChatData():
    def __init__(self, data_path, people_name, refresh=True):
        '''
        :param data_path: 全部微信聊天记录.csv文件
        :param people_name: 要分析的聊天对象的名称
        :param refresh: 默认为True，删除之前的历史输出
        '''
        self.data_path = data_path
        self.people_name = people_name

        self.chat_type = [] # 文本消息or其他消息
        self.chat_isSend = [] # 发送方是自己还是对面
        self.chat_time = [] # 聊天时间
        self.chat_content = []  # 聊天内容,['aa','bb',...]
        self.chat_all = []

        # 文件夹初始化
        self.save_data_path = r"data\{}".format(self.people_name)
        self.outputs_path = r"outputs\{}".format(self.people_name)
        if refresh and os.path.exists(self.save_data_path):
            shutil.rmtree(self.save_data_path)
        if refresh and os.path.exists(self.outputs_path):
            shutil.rmtree(self.outputs_path)
        os.makedirs(self.save_data_path, exist_ok=True)
        os.makedirs(self.outputs_path, exist_ok=True)

        self.getData() # 数据初始化
        self.hour_set = [self.to_hour(i) for i in self.chat_time]


    # 读取原数据，初始化
    def getData(self):
        # type,isSend,time,talker,content
        chat = pd.read_csv(self.data_path, sep=',', usecols=[2,4,6,7,8])

        # 对于每一条聊天数据
        for i in range(len(chat) - 1):
            content = chat[i:i + 1]

            # 如果是跟当前想分析的那个人的
            if content['talker'].values[0] == PEOPLE[self.people_name]:
                type = content['type'].values[0]
                isSend = content['isSend'].values[0]
                t = content['createTime'].values[0] // 1000
                c = content['content'].values[0]
                self.chat_type.append(type)
                self.chat_isSend.append(isSend)
                self.chat_time.append(t)
                self.chat_content.append(c)
                self.chat_all.append([type, isSend, t, c])

        self.chat_all = sorted(self.chat_all, key=itemgetter(2))  # 以时间顺序排序

    # 聊天记录保存，图片信息等不保存
    def saveChat(self):
        # 1.根据type
        msg = []
        for i, line in enumerate(self.chat_content):
            if self.chat_type[i] == 1: # 文本信息
                # 2.个人聊天直接保存，群聊需去掉用户名
                if re.match(r'.*(chatroom)', PEOPLE[self.people_name]):
                    if re.match(r'(wxid).*', line):
                        line = ''.join(line.split('\n')[1:])

                msg.append(line+'\n')

        write2txt(''.join(msg), os.path.join(self.save_data_path, 'all_chat.txt'))


    # 转换时间格式为24h制
    def to_hour(self, t):
        struct_time = time.localtime(t)
        hour = round((struct_time[3] + struct_time[4] / 60), 2)
        return hour

    # 聊天时间统计图画图
    def draw(self, show=False):
        myfont = FontProperties(fname=r'C:\Windows\Fonts\MSYH.TTC', size=22)  # 标题字体样式
        myfont2 = FontProperties(fname=r'C:\Windows\Fonts\MSYH.TTC', size=18)  # 横纵坐标字体样式
        sns.set_style('darkgrid')  # 设置图片为深色背景且有网格线
        sns.distplot(self.hour_set, 24, color='lightcoral')
        plt.xticks(np.arange(0, 25, 1.0), fontsize=15)
        plt.yticks(fontsize=15)
        plt.title('聊天时间分布', fontproperties=myfont)
        plt.xlabel('时间段', fontproperties=myfont2)
        plt.ylabel('聊天时间分布', fontproperties=myfont2)
        fig = plt.gcf()
        fig.set_size_inches(20, 10)
        fig.savefig(os.path.join(self.outputs_path, 'chat_time.png'), dpi=100)
        if show:
            plt.show()

    # 聊天时段数据统计,late=True表示额外输出22-02点的聊天记录
    def timeSta(self, late=False):
        time_slice = [0, 0, 0, 0, 0, 0]
        labels = ['凌晨2点至6点', '6点至10点', '10点至14点',
                  '14点至18点', '18点至22点', '22点至次日凌晨2点']
        deep_night = []  # 22-02点

        for i in range(len(self.hour_set)):
            if self.hour_set[i] >= 2 and self.hour_set[i] < 6:
                time_slice[0] += 1
            elif self.hour_set[i] >= 6 and self.hour_set[i] < 10:
                time_slice[1] += 1
            elif self.hour_set[i] >= 10 and self.hour_set[i] < 14:
                time_slice[2] += 1
            elif self.hour_set[i] >= 14 and self.hour_set[i] < 18:
                time_slice[3] += 1
            elif self.hour_set[i] >= 18 and self.hour_set[i] < 22:
                time_slice[4] += 1
            else:
                time_slice[5] += 1
                if late:
                    deep_night.append([self.chat_time[i], self.chat_content[i]])

        time_distribution = {
            labels[0]: time_slice[0],
            labels[1]: time_slice[1],
            labels[2]: time_slice[2],
            labels[3]: time_slice[3],
            labels[4]: time_slice[4],
            labels[5]: time_slice[5]
        }

        print("共计聊天记录： {}条".format(len(self.chat_content)))
        print(time_distribution)
        write2txt("共计聊天记录： {}条".format(len(self.chat_content)), os.path.join(self.outputs_path, 'out.txt'))
        write2txt(time_distribution, os.path.join(self.outputs_path, 'out.txt'))

        # 深夜聊天记录统计
        if late:
            wbk = xlwt.Workbook()
            sheet = wbk.add_sheet('late')
            for i in range(len(deep_night)):
                sheet.write(i, 0, time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(deep_night[i][0])))
                sheet.write(i, 1, deep_night[i][1])
            wbk.save(os.path.join(self.save_data_path, 'late_chat.xls'))

    # 关键字，字符统计
    def countChar(self):
        pattern1 = '.*?(收到).*?'
        pattern2 = '.*?(好的).*?'
        pattern3 = '.*?(老师).*?'
        pattern4 = '.*?(论文).*?'
        pattern5 = '.*?(可以).*?'
        pattern_set = [pattern1, pattern2, pattern3, pattern4, pattern5]
        statistic = [0, 0, 0, 0, 0]

        for i in range(len(self.chat_content)):
            for j in range(len(pattern_set)):
                length = len(re.findall(pattern_set[j], str(self.chat_content[i])))
                statistic[j] += length

        result = {
            '收到': statistic[0],
            '好的': statistic[1],
            '老师': statistic[2],
            '论文': statistic[3],
            '可以': statistic[4]
        }

        print(result)
        write2txt(result, os.path.join(self.outputs_path, 'out.txt'))

    # 双方各自发送的信息条数统计
    def countPeoNum(self):
        self_num = 0
        people_num = 0

        for f in self.chat_isSend:
            if f==1:
                self_num += 1
            else:
                people_num += 1

        p = "自己发送的信息条数：{}，对方发送的信息条数：{}".format(self_num, people_num)
        print(p)
        write2txt(p, os.path.join(self.outputs_path, 'out.txt'))

    # 返回保存的聊天记录txt
    def getChatPath(self):
        return os.path.join(self.save_data_path, 'all_chat.txt')